package com.kaifamiao.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;

import javax.annotation.Resource; // JSR 250
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.logging.Logger;

@Controller
@RequestMapping("/file/**")
public class FileController {

    // 根据类型自动装配
    @Autowired
    private Logger logger;

    // 根据名称自动装配
    // @Autowired @Qualifier("location")
    @Resource( name = "location" )
    private String location;

    @GetMapping("/upload")
    public String upload() {
        logger.info( "打开文件上传页面" );
        // 返回 视图名称 ( view name )
        return "file/upload";
    }

    @PostMapping("/upload/single/first")
    @ResponseBody
    public Map<String,Object> upload( @RequestParam("upfile") MultipartFile mf,
                                      @RequestParam("description") String desc ) {
        logger.info( "文件上传" );
        logger.info( desc );
        try {
            InputStream in = mf.getInputStream();
            String original = mf.getOriginalFilename();
            File target = new File(location, original);
            OutputStream out = new FileOutputStream(target);
            in.transferTo(out);
            return Map.of( "success", true, "message", "上传成功" );
        } catch ( IOException e ) {
            return Map.of( "success", false, "message", "上传失败" ,"reason", e.getMessage() );
        }
    }

    @PostMapping("/upload/single/second")
    @ResponseBody
    public Map<String,Object> upload(HttpServletRequest request) {
        return Map.of( "success", true, "message", "上传成功" );
    }

    @PostMapping("/upload/single/third")
    @ResponseBody
    public Map<String,Object> upload(MultipartRequest request) {
        return Map.of( "success", true, "message", "上传成功" );
    }

    @PostMapping("/upload/single/fourth")
    @ResponseBody
    public Map<String,Object> upload( @RequestPart("upfile")  Part part ) {
        return Map.of( "success", true, "message", "上传成功" );
    }

    @PostMapping("/upload/batch")
    @ResponseBody
    public Map<String, Object> upload( @RequestPart("upfile")  List<MultipartFile> files) {
        logger.info( "文件上传" );
        Map<String,Object> map = new HashMap<>();
        List<String> succeed = new ArrayList<>();
        List<String> failed = new ArrayList<>();
        Iterator<MultipartFile> itor = files.iterator();
        while ( itor.hasNext() ) {
            MultipartFile file = itor.next();
            final String filename = file.getOriginalFilename();
            Path target = Path.of( location, filename );
            try {
                Files.copy(file.getInputStream(), target, StandardCopyOption.REPLACE_EXISTING);
                succeed.add( filename );
            } catch ( IOException e ) {
                logger.warning( e.getMessage() );
                failed.add( filename );
            }
        }
        map.put( "succeed", succeed );
        map.put( "failed", failed );
        return map;
    }

    @GetMapping("/list")
    public String list( Map<String,Object> map ) {
        File dir = new File( location );
        File[] array = dir.listFiles();
        map.put( "files", array );
        return "file/list"; // 返回视图名称(view name)
    }

    @GetMapping("/download/{filename}")
    public ResponseEntity<byte[]> download( @PathVariable("filename") String filename ) {
        logger.info("下载" + filename );
        byte[] body = null;
        File f = new File( location, filename );
        try {
            InputStream in = new FileInputStream(f);
            body = in.readAllBytes();
        } catch ( IOException e ) {
            e.printStackTrace();
        }

        HttpHeaders headers = new HttpHeaders();
        headers.setContentDisposition( ContentDisposition.attachment().filename( filename ).build() );
        // headers.set( "content-disposition", "attachment; filename=" + filename );

        return new ResponseEntity<>( body, headers, HttpStatus.OK );
    }

}
